package prj3.ui;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.GregorianCalendar;
import java.util.Iterator;

import javax.swing.JPanel;

import prj3.EarthGrid;
import prj3.EarthSim;
import prj3.SphericalCell;
import prj3.exceptions.EmptyListException;
import util.Conversions;
import util.DateUtil;
 
public class EarthDisplay extends JPanel
{
	double xInc, yInc;
    final int
        GRID_SIZE = 180,
        DRAW      = 0,
        FILL      = 1,
        PAD       = 30;
    EarthGrid grid;
    
    EarthSim sim;
    
    Toolkit tk;
    Image sun;
    ColorPicker colorPicker;
    
    public EarthDisplay(EarthGrid grid, EarthSim sim, int maxValue)
    {
    	colorPicker = new ColorPicker(maxValue);
        tk = Toolkit.getDefaultToolkit();
        sun = tk.getImage("resources/sun.gif");
        this.sim = sim;
        this.grid = grid;
        if(grid != null){
            grid.setDisplay(this);
        }
        CellSelector cellSelector = new CellSelector(this);
        this.addMouseListener(cellSelector);
        setSize(700,700);
        setVisible(true);
        
    }
    
    public void setGrid(EarthGrid grid){
        this.grid = grid;
        if(grid != null){
            grid.setDisplay(this);
        }
    }
    
    
 
 
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        double averageTemp = 0;
        
        double w = getWidth();
        double h = getHeight();
        if(grid != null){
            boolean error = true;
            GregorianCalendar simulatedTimeStep = null;
            double sunAngleRadians = 0;
                try{
                   simulatedTimeStep = grid.takeSimulatedTimeStep();
                   sunAngleRadians = grid.takeSunAngle();
                } catch (EmptyListException e){
                    return;
                }
            sim.simulatedTime.setText(DateUtil.dateString(simulatedTimeStep));
            int sunAngle = (int)Conversions.radToDeg(sunAngleRadians);
            int xCoordSunAngle = (int)((sunAngle / 360.0) * w) - sun.getWidth(null) / 2;
            g2.drawImage(sun, xCoordSunAngle, (int)h-40, null);
            int maxLatitude = grid.getMaximumLatitude();
            int maxLongitude = grid.getMaximumLongitude();
            int degreeFactorLatitude = (int)Conversions.radToDeg(grid.getStepTheta());
            int degreeFactorLongitude = (int)Conversions.radToDeg(grid.getStepPhi());
            xInc = (w - 2*PAD)/maxLongitude;
            yInc = (h - 2*PAD)/maxLatitude;
            // row lines
            double x1 = PAD, y1 = PAD, x2 = w - PAD, y2 = h - PAD;
            for(int j = 0; j <= maxLatitude; j++)
            {
                g2.draw(new Line2D.Double(x1, y1, x2, y1));
                if (j % 1 == 0){
                    String lat;
                    if(j > maxLatitude / 2){
                        lat = Math.abs((degreeFactorLatitude * (maxLatitude/2 - j))) + "\u00B0" + "S";
                    } else {
                        lat = (degreeFactorLatitude * (maxLatitude/2 - j)) + "\u00B0" + "N";
                    }
                    g2.drawString(lat, (int)x1 - 30, (int)y1);
                }
                y1 += yInc;
            }
            // col lines
            y1 = PAD;
            for(int j = 0; j <= maxLongitude; j++)
            {
                g2.draw(new Line2D.Double(x1, y1, x1, y2));
                if (j % 2 == 0){
                	g2.drawString((degreeFactorLongitude * j) + "\u00B0", (int)x1, (int)y1);
                }
                x1 += xInc;
            }
            // fill cells
            Iterator it = grid.iterator();
            int numCells = 0;
            while(it.hasNext()){
                SphericalCell cell = (SphericalCell) it.next();
                int row = cell.getCoordinate().getLatitude();
                int col = cell.getCoordinate().getLongitude();
                float value = 0;
                error = true;
                while (error){
                    try{
                        value = cell.takeValue();
                        error = false;
                    } catch (EmptyListException e){
                        error = true;
                    }
                }
                averageTemp += value;
                numCells++;
                g2.setPaint(colorPicker.getRednessColor(value));
                //System.out.println("Row: " + row + ", Col: " + col + ", Temp: " + cell.getValue());
                
                x1 = PAD + col * xInc + 1;
                y1 = PAD + (row-1) * yInc + 1;
                g2.fill(new Rectangle2D.Double(x1, y1, xInc - 1, yInc - 1));
            }
            //System.out.println("Average World Temp: " + (averageTemp / numCells));
        } else {
            g2.drawRect(0, 0, (int)w, (int)h);
        }
        
    }
    
    public void updateDisplay(EarthGrid grid){
        //System.out.println("Updated Grid");
        this.grid = grid;
        paintImmediately(0, 0, getWidth(), getHeight());
    }
 
    public void toggleCellColor(int row, int col)
    {
        double w = getWidth();
        double h = getHeight();
        int maxLatitude = grid.getMaximumLatitude();
        int maxLongitude = grid.getMaximumLongitude();
        int degreeFactorLatitude = (int)Conversions.radToDeg(grid.getStepTheta());
        int degreeFactorLongitude = (int)Conversions.radToDeg(grid.getStepPhi());
        System.out.println("Row: " + row + ", Col: " + col);
        
    }
 
    
   

    
    
    
}
 
 
class CellSelector extends MouseAdapter
{
    EarthDisplay earthDisplay;
 
    public CellSelector(EarthDisplay ed)
    {
    	earthDisplay = ed;
    }
 
    public void mousePressed(MouseEvent e)
    {
        Point p = e.getPoint();
        int col = 0, row = 0;
        double x = earthDisplay.PAD + earthDisplay.xInc;
        // find column
        for(int j = 0; j < earthDisplay.GRID_SIZE; j++)
        {
            if(p.x < x)
            {
                col = j;
                break;
            }
            x += earthDisplay.xInc;
        }
        // find row
        double y = earthDisplay.PAD + earthDisplay.yInc;
        for(int j = 0; j < earthDisplay.GRID_SIZE; j++)
        {
            if(p.y < y)
            {
                row = j;
                break;
            }
            y += earthDisplay.yInc;
        }
        earthDisplay.toggleCellColor(row, col);
    }
}


